from sqlalchemy import Column, Integer, String, Float, DateTime, func, ForeignKey
from sqlalchemy.orm import relationship
from .base import db
from flask import current_app
from .application import Application


class Mission(db.Model):
    __tablename__ = 'missions'
    id = Column(Integer, nullable=False, primary_key=True)
    type = Column(String(20), nullable=False)
    title = Column(String(40), nullable=False)
    description = Column(String(200), nullable=False, default="这个人很懒，什么也没写")
    people = Column(Integer, nullable=False)
    credit_per_people = Column(Float(precision=2), nullable=False)
    deadline = Column(DateTime, nullable=False)
    picture = Column(String(200), nullable=True)
    created = Column(DateTime, server_default=func.now(), comment='创建时间')
    updated = Column(DateTime, server_default=func.now(),
                     onupdate=func.now(), comment='修改时间')
    state = Column(Integer, nullable=False, default=0)

    owner_id = Column(Integer, ForeignKey('users.id'))

    applications = relationship('Application', backref='mission')

    def save(self):
        db.session.add(self)
        db.session.commit()

    @staticmethod
    def query_by_applier(identify: int):
        mission_ids = [
            app.mission_id for app in Application.query.filter_by(applier_id=identify)]
        current_app.logger.info("mission_ids {}".format(mission_ids))
        return Mission.query.filter(Mission.id.in_(mission_ids)).all()

    @staticmethod
    def query_by_id(identify: int):
        return Mission.query.filter_by(id=identify).one_or_none()

    @staticmethod
    def update_by_id(identify: int, attrs: dict):
        Mission.query.filter_by(id=identify).update(attrs)
        db.session.commit()
        return Mission.query_by_id(identify)

    @staticmethod
    def delete_mission(mission):
        db.session.delete(mission)
        db.session.commit()

    @staticmethod
    def accept_one(identify: int):
        mission = Mission.query_by_id(identify)
        accepted = list(filter(lambda x: x.state == 1, mission.applications))
        if len(accepted) >= mission.people:
            Mission.update_by_id(identify, {'state': '1'})

    @ staticmethod
    def complete_one(identify: int):
        mission = Mission.query_by_id(identify)
        completed = 0
        for app in mission.applications:
            if app.state == 3:
                completed += 1
        if completed >= mission.people:
            Mission.update_by_id(identify, {'state': '2'})

    def __repr__(self):
        return f'<User {self.title!r}>'
